package controllers

import (
	"github.com/milkbobo/fishgoweb/crypto"
	"github.com/milkbobo/fishgoweb/language"
	"go.mongodb.org/mongo-driver/mongo/options"
	"miners-monitor/models/client"
	"miners-monitor/models/common"
	"miners-monitor/models/miner"
)

type ClientController struct {
	BaseController
	CommonFunc common.CommonFunc
	ClientAo   client.ClientAoModel
	MinerAo    miner.MinerAoModel
}

func (this *ClientController) Search_Json() interface{} {
	this.ClientAo.IsLoginAndCheckoutAuth(client.ClientAuthorityEnum.AccountManagement)
	clientData := client.Client{
		Name:     this.Ctx.GetParam("Name"),
		ClientId: this.Ctx.GetParam("ClientId"),
	}
	return this.ClientAo.Search(clientData)
}

func (this *ClientController) Register_Json() {
	user := this.ClientAo.IsLoginAndCheckoutAuth(client.ClientAuthorityEnum.AccountManagement)
	clientData := this.checkClient()
	searchData := client.Client{Name: clientData.Name}
	clientResult := this.ClientAo.FindOne(searchData, options.FindOne())
	if clientResult.ClientId != "" || clientResult.Name != "" {
		language.Throw(1, "用户名已经存在，请重新输入")
	}
	if len(clientData.Authority) == 0 {
		language.Throw(1, "权限不能为空")
	}
	password, err := crypto.PasswordHash([]byte(clientData.Password), crypto.BCRYPT)
	if err != nil {
		panic(err)
	}
	clientData.Password = password
	this.Log.Debug("%+v", clientData)
	this.ClientAo.Upsert(clientData)
	this.Log.Notice("管理员%s,$s注册了用户$+v", user.ClientId, user.Name, clientData)
}

func (this *ClientController) Update_Json() {

	clientData := client.Client{}
	this.CommonFunc.PostToStruct(&clientData)

	clientLogin := this.ClientAo.IsLogin()
	this.Log.Debug("%+v", clientData.ClientId)

	if clientData.ClientId == "" {
		language.Throw(1, "用户ID不能为空")
	}

	isAccountManagement := false
	for _, s := range clientLogin.Authority {
		if s == client.ClientAuthorityEnum.AccountManagement {
			isAccountManagement = true
			this.Log.Debug("%+v", isAccountManagement)
			break
		}
	}

	if clientLogin.ClientId != clientData.ClientId &&
		len(clientData.Authority) > 0 {
		if !isAccountManagement {
			language.Throw(1, "抱歉，你没有该页面的权限")
		}
	}

	searchData := client.Client{ClientId: clientData.ClientId}
	clientResult := this.ClientAo.FindOne(searchData, options.FindOne())
	if clientResult.ClientId == "" {
		language.Throw(1, "用户不存在")
	}
	if len(clientData.Password) > 0 {
		password, err := crypto.PasswordHash([]byte(clientData.Password), crypto.BCRYPT)
		if err != nil {
			panic(err)
		}
		clientData.Password = password
	}
	clientData.Name = clientResult.Name
	if !isAccountManagement {
		clientData.Authority = []string{}
	}
	this.ClientAo.Update(clientData)
	this.Log.Notice("管理员%s,%s更新了用户%+v", clientLogin.ClientId, clientLogin.Name, clientData)
}

func (this *ClientController) Login_Json() interface{} {

	clientData := this.checkClient()
	searchData := client.Client{Name: clientData.Name}
	clientResult := this.ClientAo.FindOne(searchData, options.FindOne())
	if clientResult.ClientId == "" {
		language.Throw(1, "用户名或者密码错误，请重新输入")
	}
	if clientResult.Password == "" {
		language.Throw(1, "用户名或者密码错误，请重新输入")
	}
	verify, err := crypto.PasswordVerify([]byte(clientData.Password), clientResult.Password)
	if err != nil {
		panic(err)
	}
	if verify == false {
		language.Throw(1, "用户名或者密码错误，请重新输入")
	}
	sess, err := this.Session.SessionStart()
	if err != nil {
		this.Log.Debug("%+v", err)
		panic("session启动失败:" + err.Error())
	}

	defer sess.SessionRelease()
	sess.Set("clientId", clientResult.ClientId)
	clientResult.Password = ""
	return clientResult
}

func (this *ClientController) GetAuthority_Json() interface{} {
	minerIds := this.MinerAo.GetMinerIds()
	auth := client.ClientAuthorityEnum.Names()
	result := map[string]string{}
	for _, singleMinerId := range minerIds {
		result[singleMinerId] = singleMinerId
	}
	for k, v := range auth {
		result[k] = v
	}
	return result
}

func (this *ClientController) IsLogin_Json() interface{} {
	result := this.ClientAo.IsLogin()
	result.Password = ""
	return result
}

func (this *ClientController) GetByClientId_Json() interface{} {

	clientData := this.ClientAo.IsLogin()

	clientId := this.Ctx.GetParam("ClientId")
	this.Log.Debug("%+v", clientId)

	if clientId == "" {
		language.Throw(1, "用户ID不能为空")
	}

	if clientData.ClientId != clientId {
		isAccountManagement := false
		for _, s := range clientData.Authority {
			if s == client.ClientAuthorityEnum.AccountManagement {
				isAccountManagement = true
				break
			}
		}
		if !isAccountManagement {
			language.Throw(1, "抱歉，你没有该页面的权限")
		}
	}

	result := this.ClientAo.FindOne(client.Client{ClientId: clientId}, options.FindOne())
	result.Password = ""
	return result
}

func (this *ClientController) Del_Json() {
	user := this.ClientAo.IsLoginAndCheckoutAuth(client.ClientAuthorityEnum.AccountManagement)
	clientId := this.Ctx.GetParam("ClientId")
	this.Log.Debug("%+v", clientId)

	if clientId == "" {
		language.Throw(1, "用户ID不能为空")
	}
	clientData := this.ClientAo.FindOne(client.Client{ClientId: clientId}, options.FindOne())

	result := this.ClientAo.Del(clientId)
	if result.DeletedCount == 0 {
		language.Throw(1, "删除失败")
	}
	this.Log.Notice("管理员%s,%s删除了用户%+v", user.ClientId, user.Name, clientData)

}

func (this *ClientController) checkClient() client.Client {
	clientData := client.Client{}
	this.CommonFunc.PostToStruct(&clientData)

	clientData.ClientId = ""
	if clientData.Name == "" {
		language.Throw(1, "用户名不能为空")
	}
	if clientData.Password == "" {
		language.Throw(1, "密码不能为空")
	}
	return clientData
}

func (this *ClientController) GetMenu_Json() interface{} {
	//minerIds := this.MinerAo.GetMinerIds()

	user := this.ClientAo.IsLogin()

	result := []client.ClientMenu{
		{
			Path:     "/",
			Redirect: "/welcome",
		},
		{
			Path: "/welcome",
			Name: "概览",
		},
		{
			Path: "/minersMonitor",
			Name: "矿工监控",
		},
		{
			Path: "/income",
			Name: "收入监控",
		},
		{
			Path: "/expend",
			Name: "支出监控",
		},
	}

	accessControl := false
	for _, v := range user.Authority {
		if v == client.ClientAuthorityEnum.AccountManagement ||
			v == client.ClientAuthorityEnum.MinersManagement {
			accessControl = true
			break
		}
	}

	if accessControl {
		result = append(result, client.ClientMenu{
			Name: "访问控制",
			Children: []client.ClientMenu{
				{
					Path:      "/userList",
					Name:      "账户管理",
					Authority: []string{client.ClientAuthorityEnum.AccountManagement},
				},
				{
					Path:      "/minerList",
					Name:      "矿工管理",
					Authority: []string{client.ClientAuthorityEnum.MinersManagement},
				},
			},
		})
	}

	//for _, singleMinerId := range minerIds {
	//	result = append(result, client.ClientMenu{
	//		Path:      "/minerInfo/" + singleMinerId,
	//		Name:      singleMinerId,
	//		Authority: []string{"singleMinerId"},
	//	})
	//}

	return result
}
